package com.t4l.client;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.RootPanel;
import com.t4l.client.screens.login.Login;
import com.t4l.client.screens.login.main.MainScreen;
import com.t4l.client.services.login.LoginService;
import com.t4l.client.services.login.LoginServiceAsync;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class T4l implements EntryPoint {

	private LoginServiceAsync fbService = GWT.create(LoginService.class);

	private JSONObject userInfo = null;

	private Login login = null;

	public void onModuleLoad() {
		login = new Login(this);
		validateLogin();
	}

	public void in() {
		RootPanel.get().remove(login);
		MainScreen main = new MainScreen();
		RootPanel.get().add(main);
	}

	/**
	 * Validate if user has been logged in
	 * 
	 * @return
	 */
	private void validateLogin() {
		fbService.getUserInfo(new AsyncCallback<String>() {
			@Override
			public void onFailure(Throwable caught) {
				goToLogin();
			}

			@Override
			public void onSuccess(String result) {
				if (result == null) {
					HashMap<String, String> hashValues = getHashValues();
					if (isAfterLoginOnFacebook(hashValues)) {
						validateLoginWithFacebook(hashValues);
					} else {
						goToLogin();
					}
				} else {
					JSONValue parseStrict = JSONParser.parseStrict(result);
					setUserInfo(parseStrict.isObject());
					in();
				}
			}
		});
	}

	public void setUserInfo(JSONObject userInfo) {
		this.userInfo = userInfo;
	}

	private void goToLogin() {
		RootPanel.get().add(login);
	}

	/**
	 * Validate login with facebook
	 * 
	 * @param hashValues
	 * @return
	 */
	private void validateLoginWithFacebook(HashMap<String, String> hashValues) {
		final List<String> error = new ArrayList<String>();
		fbService.validateFacebookLogin(hashValues.get("access_token"),
				Integer.parseInt(hashValues.get("expires_in")),
				new AsyncCallback<String>() {
					@Override
					public void onSuccess(String result) {
						JSONValue parseStrict = JSONParser.parseStrict(result);
						T4l.this.userInfo = parseStrict.isObject();
						in();
					}

					@Override
					public void onFailure(Throwable caught) {
						Window.alert(caught.getMessage());
						error.add(caught.getMessage());
					}
				});
	}

	/**
	 * Validate if request is made after login on facebook
	 * 
	 * @param hashValues
	 * @return
	 */
	private boolean isAfterLoginOnFacebook(HashMap<String, String> hashValues) {
		return hashValues.get("access_token") != null
				&& hashValues.get("expires_in") != null;
	}

	/**
	 * Get hash values from url
	 * 
	 * @return
	 */
	private HashMap<String, String> getHashValues() {
		HashMap<String, String> hashValues = new HashMap<String, String>();
		String hash = Window.Location.getHash();
		if (hash.startsWith("#")) {
			hash = hash.substring(1);
		}
		if (hash.length() > 0) {
			String[] hashParts = hash.split("&");
			for (String hashPart : hashParts) {
				String[] pairs = hashPart.split("=");
				hashValues.put(pairs[0], pairs[1]);
			}
		}
		return hashValues;
	}
}
